Creating custom roles that allow privilege escalation can allow attackers to maliciously exploit an organization’s cloud resources.
Certain GCP permissions allow impersonation of one or more privileged principals within a GCP infrastructure.
To prevent privilege escalation
after an account has been compromised, proactively follow GCP Security Insights and ensure that custom roles contain as few privileges as possible
that allow direct or indirect impersonation.
For example, privileges like deploymentmanager.deployments.create
allow impersonation of service accounts, even if the name does not
sound like it.
Other privileges like setIamPolicy
, which are more explicit, directly allow their holder to extend their
privileges.
After gaining a foothold in the target infrastructure, sophisticated attackers typically map their newfound roles to understand what is
exploitable.
The riskiest privileges are either:
- At the infrastructure level: privileges to perform project, folder, or organization-wide administrative tasks.
- At the resource level: privileges to perform resource-wide administrative tasks.
In either case, the following privileges should be avoided or granted only with caution:
-
..setIamPolicy
-
cloudbuilds.builds.create
-
cloudfunctions.functions.create
-
cloudfunctions.functions.update
-
cloudscheduler.jobs.create
-
composer.environments.create
-
compute.instances.create
-
dataflow.jobs.create
-
dataproc.clusters.create
-
deploymentmanager.deployments.create
-
iam.roles.update
-
iam.serviceAccountKeys.create
-
iam.serviceAccounts.actAs
-
iam.serviceAccounts.getAccessToken
-
iam.serviceAccounts.getOpenIdToken
-
iam.serviceAccounts.implicitDelegation
-
iam.serviceAccounts.signBlob
-
iam.serviceAccounts.signJwt
-
orgpolicy.policy.set
-
run.services.create
-
serviceusage.apiKeys.create
-
serviceusage.apiKeys.list
-
storage.hmacKeys.create
Ask Yourself Whether
- This role requires impersonation to perform specific tasks with different privileges.
- This custom role is intended for a small group of administrators.
There is a risk if you answered no to these questions.
Recommended Secure Coding Practices
Use a permission that does not allow privilege escalation.
Sensitive Code Example
Lightweight custom role intended for a developer:
resource "google_organization_iam_custom_role" "example" {
permissions = [
"iam.serviceAccounts.getAccessToken", # Sensitive
"iam.serviceAccounts.getOpenIdToken", # Sensitive
"iam.serviceAccounts.actAs", # Sensitive
"iam.serviceAccounts.implicitDelegation", # Sensitive
"resourcemanager.projects.get",
"resourcemanager.projects.list",
"run.services.create",
"run.services.delete",
"run.services.get",
"run.services.getIamPolicy",
"run.services.list",
"run.services.update",
]
}
Lightweight custom role intended for a read-only user:
resource "google_project_iam_custom_role" "example" {
permissions = [
"iam.serviceAccountKeys.create", # Sensitive
"iam.serviceAccountKeys.get", # Sensitive
"deploymentmanager.deployments.create", # Sensitive
"cloudbuild.builds.create", # Sensitive
"resourcemanager.projects.get",
"resourcemanager.projects.list",
"run.services.get",
"run.services.getIamPolicy",
"run.services.list",
]
}
Compliant Solution
Lightweight custom role intended for a developer:
resource "google_project_iam_custom_role" "example" {
permissions = [
"resourcemanager.projects.get",
"resourcemanager.projects.list",
"run.services.create",
"run.services.delete",
"run.services.get",
"run.services.getIamPolicy",
"run.services.list",
"run.services.update",
]
}
Lightweight custom role intended for a read-only user:
resource "google_project_iam_custom_role" "example" {
permissions = [
"resourcemanager.projects.get",
"resourcemanager.projects.list",
"run.services.get",
"run.services.getIamPolicy",
"run.services.list",
]
}
See